;; -*- auto-recompile: t -*-
;;; capital.el --- yet another sentence-capitalization utility(ies). 
;; Time-stamp: <2002-05-10 10:19:52 deego>
;; Copyright (C) 2002 D. Goel
;; Copyright (C) 2002 Free Software Foundation, Inc.
;; Emacs Lisp Archive entry
;; Filename: capital.el
;; Package: capital
;; Author: D. Goel <deego@glue.umd.edu>
;; Version: 0.0alpha

;; Namespace: capital-

;; For latest version: 

(defvar capital-home-page  "http://www.glue.umd.edu/~deego")


 
;; This file is NOT (yet) part of GNU Emacs.
 
;; This is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
 
;; This is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING.  If not, write to the
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
 

;; See also:
;Kevin Rodger's auto-capitalize.el
;lazy-capitalize.el?
;; Quick start:
(defvar capital-quick-start
  "Help..."
)

;;;###autoload
(defun capital-quick-start ()
  "Provides electric help regarding `capital-quick-start'."
  (interactive)
  (with-electric-help
   '(lambda () (insert capital-quick-start) nil) "*doc*"))

;;; Introduction:
;; Stuff that gets posted to gnu.emacs.sources
;; as introduction
(defvar capital-introduction
  "capital.el is yet another sentence-capitalization utility(ies).   Note
that there's auto-capitalize.el and laxy-capitalize(?).el out there.
Type M-x capital-commentary for more gory details of differences..

PS: By frobbing the values of various defcustom's, you can turn off or
on various prompts..


Note that the main function here is capital-buffer, and was designed
to work unannoyingly when all the defcustom- variables are set to zero.  All
others, like capital-region, capital-buffer-query are quick
derivatives.. and have minor quirks.. 

for instance:
[1] when querying, cursor is not shown.
[2] when capitalizing region, the first character in the region always
gets capitalized.. even if it is not a beginning of a sentence..
"
)

;;;###autoload
(defun capital-introduction ()
  "Provides electric help regarding `capital-introduction'."
  (interactive)
  (with-electric-help
   '(lambda () (insert capital-introduction) nil) "*doc*"))

;;; Commentary:
(defvar capital-commentary
  "There are several libraries out there to capitalize.. then why did i
write this?  Some motivations:

* This one respects namespace and everything starts with capital-

* I do not like the default capitalize-word in Emacs, because it is
  too aggressive---it converts GNU into Gnu.  capital.el provides an
  alternative to that, and of course, lets you choose which one you
  prefer to use. 

* I was missing such functions as M-x capital-region, M-x
  capital-buffer, M-x capital-query-region M-x capital-query-buffer
  etc. 

Might merge others with this one some day. 
"
)

;;;###autoload
(defun capital-commentary ()
  "Provides electric help regarding `capital-commentary'."
  (interactive)
  (with-electric-help
   '(lambda () (insert capital-commentary) nil) "*doc*"))

;;; History:

;;; Bugs:

;;; New features:
(defvar capital-new-features
  "Help..."
)

;;;###autoload
(defun capital-new-features ()
  "Provides electric help regarding `capital-new-features'."
  (interactive)
  (with-electric-help
   '(lambda () (insert capital-new-features) nil) "*doc*"))

;;; TO DO:
(defvar capital-todo
  "
Help/patches welcome.

* Fix Kevin Rodger's auto-capitalize's namespace, and possibly merge
  capital.el with his auto-capital.el.  At the very least, borrow his
  word-specific features.

* there's something like a lazy-capitalize.el? out
  there.. check/compare/merge? "
)

;;;###autoload
(defun capital-todo ()
  "Provides electric help regarding `capital-todo'."
  (interactive)
  (with-electric-help
   '(lambda () (insert capital-todo) nil) "*doc*"))

(defvar capital-version "0.0alpha")

;;==========================================
;;; Code:

(defvar capital-before-load-hooks nil)
(defvar capital-after-load-hooks nil)
(run-hooks 'capital-before-load-hooks)
(eval-when-compile (require 'cl))


;;;###autoload
(defun capital-region (beg end)
  "Capitalize the first word in each sentence.
Adapted from `article-capitalize-sentences' from gnus-art.el
"
  (interactive "*r")
  (save-excursion
    (save-restriction
      (narrow-to-region beg end)
      (capital-buffer))))

;;;###autoload
(defun capital-region-query (beg end)
  (interactive "*r")
  (let ((capital-interactivity 100))
    (capital-region beg end)))

;;;###autoload
(defun capital-buffer-query ()
  (let ((capital-interactivity 100))
    (capital-buffer)))

;;;###autoload
(defun capital-buffer ()
  "Capitalize the entire buffer..
Whether or not you are prompted for each change etc. depends on the
value of capital-interactivity.  An experienced user may consider
choosing that variable as 0.  Also see the other defcustoms..."
  (interactive)
  (when (capital-y-or-n-p 25 "Capitalize all? ")
    (let (;;(buffer-read-only nil)
	  (paragraph-start "^[\n\^L]"))
      (goto-char (point-min))
      (while (not (eobp))
	;;(capitalize-word 1)
	(when
	    (capital-y-or-n-p -25 "Capitalize next word? ")
	  (funcall capital-word-function 1))
	;; an ignore-errors is needed for the exceptional case when
	;; the previous sentence was just one-word, which also
	;; ended the buffer..  Therefore, after capitalizing it, we
	;; find ourselves at the end of the buffer.. and calling
	;; forward-sentence now will lead to an error..
	(ignore-errors (forward-sentence))
	(capital-sit-for -10 1)
	)
      (capital-message 1 "Capitalized all!")
      (capital-sit-for 25 1))))



(defcustom capital-word-function 'capital-word
  "You may prefer the emacs default capitalize-word instead...")

;;;###autoload
(defun capital-word (&optional n)
  "Design:  Should be identical to capitalize-word, except that should
not downcase anything.. viz. should not convert GNU to Gnu"
  (let ((this-pt (point)))
    (forward-word 1)
    (upcase-initials-region this-pt (point))
    (if (and
	 (numberp n)
	 (> n 1))
	(capital-word (- n 1)))))


;;;###autoload
(defun capital-outgoing-message ()
  "Consider adding this to your message-send-hook. 
Capitalize the first word in each sentence.
Adapted from `article-capitalize-sentences' from gnus-art.el
"
  (interactive)
  (save-excursion
    (message-goto-body)
    (capital-region (point) (point-max))))



(defun capital-message (points &rest args)
  (unless (minusp (+ points capital-loudness))
    (apply #'message args)))


(defcustom capital-loudness 100
  "suggested: Anywhere from -100 to 100

The design is such that a value of 0 should be optimum. 
Once you are experienced with this library, you might prefer a value
of 0 for this variable."
  )


(defun capital-y-or-n-p (add &rest args)
  (if (minusp (+ add capital-interactivity))
      t
    (apply 'y-or-n-p args)))


(defun capital-sit-for (add &rest args)
  (if (minusp (+ add capital-interactivity))
      t
      (apply 'sit-for args)))


(defcustom capital-interactivity 100
  "suggested: Anywhere from -100 to 100.. 
if this number is too low, capital.el will ask you for less and less
confirmations. 


The design is such that a value of 0 should be optimum. 
Once you are experienced with this library, you might prefer a value
of 0 for this variable.

"
)

(defcustom capital-speed -100
  "suggested: Anywhere from -100 to 100.. 
when this number is too low, capital.el will briefly pause after each
change it makes..

The design is such that a value of 0 should be optimum. 
Once you are experienced with this library, you might prefer a value
of 0 for this variable."

)


;;; 2002-05-09 T09:48:37-0400 (Thursday)    D. Goel
;;;###autoload
(defun capital-string (string)
  (let ((capital-interactivity -100)
	(capital-loudness -100)
	(capital-speed 100))
    (with-temp-buffer
      (insert string)
      (goto-char (point-min))
      (capital-buffer)
      (buffer-substring (point-min) (point-max))
      )))

(provide 'capital)
(run-hooks 'capital-after-load-hooks)
;;; capital.el ends here
